#include "EquationSolver.hpp"
#include <iostream>

using namespace std; 

double l,h,D,beta;
double A,B,C,E;

class F : public Function{
public:
    double operator() (double x) const{
        return A*sin(x)*cos(x)+B*sin(x)*sin(x)-C*cos(x)-E*sin(x);
    }
    double derivative(double x) const{
        return A*cos(2*x)+B*sin(2*x)+C*sin(x)-E*cos(x);
    }
};

void solve_Fa() {
    l=89,h=49,D=55,beta=11.5/180*M_PI;
    A=l*sin(beta),B=l*cos(beta),C=(h+0.5*D)*sin(beta)-0.5*D*tan(beta),E=(h+0.5*D)*cos(beta)-0.5*D;
    F f1;
    cout << "Solving maximum angle with Newton_Method" << endl;
    Newton_Method solver_f1(F(),33.0/180*M_PI);
    double x = solver_f1.solve();
    cout << "A root is :" << x*180/M_PI << endl;
    cout << "Error is :" << f1(x) << endl;
}

void solve_Fb() {
    l=89,h=49,D=30,beta=11.5/180*M_PI;
    A=l*sin(beta),B=l*cos(beta),C=(h+0.5*D)*sin(beta)-0.5*D*tan(beta),E=(h+0.5*D)*cos(beta)-0.5*D;
    F f2;
    cout << "Solving maximum angle with Newton_Method" << endl;
    Newton_Method solver_f2(F(),33.0/180*M_PI);
    double x = solver_f2.solve();
    cout << "A root is :" << x*180/M_PI << endl;
    cout << "Error is :" << f2(x) << endl;
}

void solve_Fc1() {
    l=89,h=49,D=55,beta=11.5/180*M_PI;
    A=l*sin(beta),B=l*cos(beta),C=(h+0.5*D)*sin(beta)-0.5*D*tan(beta),E=(h+0.5*D)*cos(beta)-0.5*D;
    F f3;
    cout << "Solving maximum angle with Secant_Method 1" << endl;
    Secant_Method solver_f3(F(),33.0/180*M_PI,M_PI/4);
    double x = solver_f3.solve();
    cout << "A root is :" << x*180/M_PI << endl;
    cout << "Error is :" << f3(x) << endl;
}

void solve_Fc2() {
    l=89,h=49,D=55,beta=11.5/180*M_PI;
    A=l*sin(beta),B=l*cos(beta),C=(h+0.5*D)*sin(beta)-0.5*D*tan(beta),E=(h+0.5*D)*cos(beta)-0.5*D;
    F f4;
    cout << "Solving maximum angle with Secant_Method 2" << endl;
    Secant_Method solver_f4(F(),33.0/180*M_PI,M_PI/2);
    double x = solver_f4.solve();
    cout << "A root is :" << x*180/M_PI << endl;
    cout << "Error is :" << f4(x) << endl;
}

void solve_Fc3() {
    l=89,h=49,D=55,beta=11.5/180*M_PI;
    A=l*sin(beta),B=l*cos(beta),C=(h+0.5*D)*sin(beta)-0.5*D*tan(beta),E=(h+0.5*D)*cos(beta)-0.5*D;
    F f5;
    cout << "Solving maximum angle with Secant_Method 3" << endl;
    Secant_Method solver_f5(F(),33.0/180*M_PI,34.86/18*M_PI);
    double x = solver_f5.solve();
    cout << "A root is :" << x*180/M_PI << endl;
    cout << "Error is :" << f5(x) << endl;
}

int main() {
    solve_Fa();
    solve_Fb();
    solve_Fc1();
    solve_Fc2();
    solve_Fc3();
    return 0;
}